package com.sixj.keycloak;

import org.jboss.logging.Logger;
import org.keycloak.component.ComponentModel;
import org.keycloak.credential.CredentialInput;
import org.keycloak.credential.CredentialInputValidator;
import org.keycloak.credential.CredentialModel;
import org.keycloak.models.*;
import org.keycloak.storage.StorageId;
import org.keycloak.storage.UserStorageProvider;
import org.keycloak.storage.user.UserLookupProvider;
import org.keycloak.storage.user.UserQueryProvider;
import org.keycloak.storage.user.UserRegistrationProvider;
import org.apache.commons.codec.digest.DigestUtils;

import java.util.Collections;
import java.util.List;
import java.util.Map;

public class EmployeeUserStorageProvider implements UserStorageProvider, UserLookupProvider,
        CredentialInputValidator, UserQueryProvider, UserRegistrationProvider {
    private static final Logger logger = Logger.getLogger(EmployeeUserStorageProvider.class);

    protected final ComponentModel model;
    protected final KeycloakSession session;
    protected final EmployeeUserStorageDao userStorageDao;

    public EmployeeUserStorageProvider(KeycloakSession session, ComponentModel model) {
        this.session = session;
        this.model = model;
        this.userStorageDao = new EmployeeUserStorageDao(model);
    }

    @Override
    public void close() {}

    // 密码类型支持
    @Override
    public boolean supportsCredentialType(String credentialType) {
        return CredentialModel.PASSWORD.equals(credentialType);
    }

    @Override
    public boolean isConfiguredFor(RealmModel realm, UserModel user, String credentialType) {
        return supportsCredentialType(credentialType);
    }

    // 核心密码校验（MD5）
    @Override
    public boolean isValid(RealmModel realm, UserModel user, CredentialInput input) {
        logger.infof("isValid: %s, %s, %s");
        if (!supportsCredentialType(input.getType()) || !(input instanceof UserCredentialModel)) {
            return false;
        }
        String inputPwd = ((UserCredentialModel) input).getValue();
        String empNo = user.getUsername();
        logger.infof("isValid: empNo: %s, inputPwd: %s", empNo, inputPwd);
        Employee emp = userStorageDao.getByEmpNoOrEmail(empNo);
        if (emp == null) return false;
        String inputMd5 = DigestUtils.md5Hex(inputPwd);
        logger.infof("isValid: inputMd5: %s, emp.getPassword(): %s", inputMd5, emp.getPassword());
        return inputMd5.equalsIgnoreCase(emp.getPassword());
    }


    // 用户查询接口（ID/用户名/Email）
    @Override
    public UserModel getUserById(String id, RealmModel realm) {
        logger.infof("getUserById: %s", id);
        String externalId = StorageId.externalId(id);
        Employee emp = userStorageDao.getById(externalId);
        if (emp == null) return null;
        return new EmployeeUserAdapter(session, realm, model, emp);
    }

    @Override
    public UserModel getUserByUsername(String username, RealmModel realm) {
        logger.infof("getUserByUsername: %s", username);
        Employee emp = userStorageDao.getByEmpNoOrEmail(username);
        if (emp == null) return null;
        return new EmployeeUserAdapter(session, realm, model, emp);
    }

    @Override
    public UserModel getUserByEmail(String email, RealmModel realm) {
        logger.infof("getUserByEmail: %s", email);
        Employee emp = userStorageDao.getByEmpNoOrEmail(email);
        if (emp == null) return null;
        return new EmployeeUserAdapter(session, realm, model, emp);
    }

    // 用户数量
    @Override
    public int getUsersCount(RealmModel realm) {
        logger.infof("getUsersCount");
        return userStorageDao.count();
    }

    // 查询全部用户
    @Override
    public List<UserModel> getUsers(RealmModel realm) {
        logger.infof("getUsers");
        List<Employee> list = userStorageDao.getUserList();
        return EmployeeUserStorageDao.toUserModels(list, session, realm, model);
    }

    // 分页查询
    @Override
    public List<UserModel> getUsers(RealmModel realm, int firstResult, int maxResults) {
        logger.infof("getUsers: %d, %d", firstResult, maxResults);
        List<Employee> list = userStorageDao.getUserList(firstResult, maxResults);
        return EmployeeUserStorageDao.toUserModels(list, session, realm, model);
    }

    // 模糊搜索（用户名/邮箱）
    @Override
    public List<UserModel> searchForUser(String keyword, RealmModel realm) {
        logger.infof("searchForUser: %s", keyword);
        List<Employee> list = userStorageDao.getByKeyword(keyword);
        return EmployeeUserStorageDao.toUserModels(list, session, realm, model);
    }

    @Override
    public List<UserModel> searchForUser(String keyword, RealmModel realm, int firstResult, int maxResults) {
        logger.infof("searchForUser: %s, %d, %d", keyword, firstResult, maxResults);
        List<Employee> list = userStorageDao.getByKeyword(keyword, firstResult, maxResults);
        return EmployeeUserStorageDao.toUserModels(list, session, realm, model);
    }

    // 未实现属性/分组相关查询
    @Override
    public List<UserModel> searchForUser(Map<String, String> params, RealmModel realm) {
        logger.infof("searchForUser: %s", params);
        List<Employee> list = userStorageDao.getUserList();
        return EmployeeUserStorageDao.toUserModels(list, session, realm, model);
    }
    @Override
    public List<UserModel> searchForUser(Map<String, String> params, RealmModel realm, int firstResult, int maxResults) {
        logger.infof("searchForUser: %s, %d, %d", params, firstResult, maxResults);
        if (params.containsKey("username")) {
            UserModel username = getUserByUsername(params.get("username"), realm);
            if (username == null){
                return Collections.emptyList();
            }
            return Collections.singletonList(username);
        }


        List<Employee> list = userStorageDao.getUserList(firstResult, maxResults);
        return EmployeeUserStorageDao.toUserModels(list, session, realm, model);
    }

    @Override
    public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group) {
        logger.infof("getGroupMembers: %s", group.getName());
        return Collections.emptyList();
    }
    @Override
    public List<UserModel> getGroupMembers(RealmModel realm, GroupModel group, int firstResult, int maxResults) {
        logger.infof("getGroupMembers: %s, %d, %d", group.getName(), firstResult, maxResults);
        return Collections.emptyList();
    }
    @Override
    public List<UserModel> searchForUserByUserAttribute(String attr, String value, RealmModel realm) {
        logger.infof("searchForUserByUserAttribute: %s, %s", attr, value);
        return Collections.emptyList();
    }

    // 用户注册
    @Override
    public UserModel addUser(RealmModel realm, String username) {
        logger.infof("addUser: %s", username);
        // 此处建议实际业务不直接插入，可实现注册逻辑；示例可用空实现或抛异常
        throw new UnsupportedOperationException("User registration not supported.");
    }

    // 用户删除
    @Override
    public boolean removeUser(RealmModel realm, UserModel user) {
        logger.infof("removeUser: %s", user.getUsername());
        // 一般企业场景下建议禁用；如需支持可补充DAO方法
        throw new UnsupportedOperationException("User deletion not supported.");
    }

    // Realm/分组/角色删除钩子
    @Override
    public void preRemove(RealmModel realm) {}
    @Override
    public void preRemove(RealmModel realm, GroupModel group) {}
    @Override
    public void preRemove(RealmModel realm, RoleModel role) {}

}
